package cn.biplam.front.template.base;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.ErrorMessage;
import cn.biplam.common.wrapper.KvMap;
import cn.biplam.common.wrapper.sqlresult.SqlResult;
import cn.biplam.front.html.HtmlDiv;
import cn.biplam.front.html.HtmlText;
import cn.biplam.front.html.HtmlValue;
import cn.biplam.front.html.base.HtmlWindow;
import cn.biplam.front.html.base.Const.Window_Event;
import cn.biplam.front.template.Template;

/**
 * 下拉框组件。
 * 可以用set方式设置下拉框的选项值。可以单个设置，也可以用SqlResult设置，
 * 用SqlResult设置时需要同时指定SqlResult中对应的选项中的id字段名和说明字段名称
 * 取值时用下拉框的（id+value）的方式	
 * @author 	WangSong
 * @create 	2009-5-6 上午09:19:37
 * @version 1.0
 */
public class Select implements Template{

	private String SelectID;
	private String defaultValue;
	private String sHomeUrl;
	private HtmlWindow select;
	private ArrayList<String> keys;
	private KvMap<String,String> options;
	private boolean cancelClick = false;
	private int iCount;
	private int maxWidth=50;
	private int showRowNum = 8;
	private int rowHeight = 20;
	private String maxheight = "100";
	
	/**外部传入的当下拉框选择变化时执行的脚本  */
	private String bindScript=null;
	private HtmlDiv nowOption;
	
	public Select(String id,String sHomeUrl){
		this(id,"",sHomeUrl);
	}
	
	/**
	 * 构造方法
	 * @param id   下拉框的id
	 * @param defaultValue  下拉框的默认值
	 * @param sHomeUrl  应用的系统路径
	 */
	public Select(String id,String defaultValue,String sHomeUrl){
		this.SelectID = id;
		this.defaultValue = defaultValue;
		this.sHomeUrl = sHomeUrl;
		this.options=new KvMap<String, String>();
		this.keys=new ArrayList<String>();
		this.iCount = 0;
	}
	
	/**
	 * 设置选择项的值
	 * @param optionId  选择项id
	 * @param optionText 选择项内容
	 * @throws ErrorMessage 
	 */
	public void set(String optionId,String optionText) throws ErrorMessage{
		optionId = this.SelectID +","+optionId;
		this.keys.add(optionId);
		this.options.put(optionId, optionText);
		this.iCount++;
	}
	
	/**
	 * 将外部容器传入的值设置成选项值
	 * @param optionData    外部容器传入值
	 * @throws ErrorMessage
	 */
	public void set(KvMap<String,String> optionData) throws ErrorMessage{
		
		Iterator<Map.Entry<String, String>> datas=optionData.getIterator();
		Map.Entry<String, String> data=null;
		while(datas.hasNext()){
			data=datas.next();
			this.keys.add(this.SelectID+","+data.getKey());
			this.options.put(this.SelectID+","+data.getKey(), data.getValue());
			this.iCount++;
		}
	}
	
	/**
	 * * 设置选择项的值
	 * @param sr SqlResult
	 * @param optionIdName SqlResult中选项id的列名
	 * @param optionTextName SqlResult中选项说明的列名
	 * @throws ErrorMessage 
	 */
	public void set(SqlResult sr,String optionIdName,String optionTextName) throws ErrorMessage{
		if(sr!=null){
			for(int i=0;i<sr.size();i++){
				options.put(this.SelectID+","+sr.get(i, optionIdName),sr.get(i, optionTextName));
				this.keys.add(this.SelectID+","+sr.get(i, optionIdName));
				this.iCount++;
			}
		}
	}
	
	/**
	 * 设置下拉框选择变化时的执行脚本
	 * @param script 脚本 
	 */
	public void setScript(String script){
		this.bindScript=script;
	}
	
	/**
	 * 取消可选项的OnClick事件
	 * @param cancelClick true:取消 false:不取消  默认:false
	 */
	public void setOnclickCancel(boolean cancelClick){
		this.cancelClick = cancelClick;
	}
	
	public HtmlWindow get() throws ErrorMessage {
		/**初始化select容器*/
		this.select = new HtmlDiv(this.SelectID,"selS");
		this.select.put(new HtmlValue("h,"+this.SelectID+"value","h,"+this.SelectID+"value",this.defaultValue));
		/**创建当前选择项*/
		this._createNowSelect();
		/**创建选择图标*/
		this._createPic();
		/**创建可选择项*/
		this._createOption();
		/**设置大小*/
		this._setStyleWH();
		this.select.setLength(this.maxWidth);
		return this.select;
	}
	
	/**
	 * 创建当前选择项
	 * @throws ErrorMessage 
	 */
	private void _createNowSelect() throws ErrorMessage{
		this.nowOption = new HtmlDiv(this.SelectID+"n","nowS"); 
		nowOption.put(new HtmlText(null,null,this.options.getByKey(this.SelectID+","+this.defaultValue)));
		nowOption.bind(Window_Event.OnClick,"showItem('"+this.SelectID+"','"+this.SelectID+"o');");
		this.select.put(nowOption);
	}
	
	/**
	 * 创建选择图标
	 * @throws ErrorMessage 
	 */
	private void _createPic() throws ErrorMessage{
		HtmlWindow pic = new HtmlDiv(this.SelectID+"b","btnS"); 
		ButtonImageSwitch sis = new ButtonImageSwitch(this.SelectID+"tt",this.sHomeUrl+"/images/sp.gif",
				this.sHomeUrl+"/images/sps.gif");
		pic.put(sis.get());
		pic.bind(Window_Event.OnClick, "showItem('"+this.SelectID+"','"+this.SelectID+"o');");
		this.select.put(pic);
	}
	
	/**
	 * 创建可选择项
	 * @throws ErrorMessage 
	 */
	private void _createOption() throws ErrorMessage{
		HtmlWindow outer = new HtmlDiv(this.SelectID+"o","selO");
		HtmlWindow inner = new HtmlDiv();
		String key=null;
		for(int i=0;i<this.options.size();i++){
			key=this.keys.get(i);
			if(key!=null&&!"".equals(key)){
				this._getOption(key,
						        this.options.getByKey(key), 
						        inner);
			}
		}
		if(this.options.size()<this.showRowNum){
			this.maxheight = TOOLS.intToString(this.rowHeight*this.options.size()+2);
		}else{
			this.maxheight = TOOLS.intToString(this.rowHeight*this.showRowNum);
		}
		outer.put(inner);
		this.select.put(outer);
	}
	
	/**
	 * 创建选择项
	 * @param id   下拉框代表对象的id值
	 * @param text 下拉框代表对象的说明
	 * @param div  容器id
	 * @throws ErrorMessage
	 */
	private void _getOption(String id,String text,HtmlWindow div) throws ErrorMessage{
		HtmlWindow opt = new HtmlText(id,"sps",text);
		if(!cancelClick){
			if(bindScript!=null){
				opt.bind(Window_Event.OnClick,"showOp('"+this.SelectID+"','"+id+"',event);"+bindScript+";");
			}else{
				opt.bind(Window_Event.OnClick,"showOp('"+this.SelectID+"','"+id+"',event);");
			}
		}
		opt.bind(Window_Event.OnmouseOver,"changeBg1(this);");
		div.put(opt);
		if(this.maxWidth<(TOOLS.getTextLength(text)+20)){
			this.maxWidth = TOOLS.getTextLength(text)+20;
		}
	}
	
	/**
	 * 根据option的内容设置下拉框的宽和高
	 * @throws ErrorMessage 
	 */
	private void _setStyleWH() throws ErrorMessage{
		this.select.setStyleWidth(this.maxWidth);
		this.select.setLength(this.maxWidth);//设置容器宽度,用于自动布局获取
		this.nowOption.setStyleWidth(this.maxWidth-20);
		select.put(new HtmlValue(SelectID+"width",SelectID+"width",TOOLS.intToString(maxWidth)));
		select.put(new HtmlValue(SelectID+"height",SelectID+"width",maxheight));
	}
}
